<?php
/**
 * $Id: taggable.php 63 2014-11-10 05:15:30Z shrey $
 * 
 * This file can not be redistributed to anyone without the permission of Giga Promoters
 * Copyright 2005 - 2008, Giga Promoters
 * 						  608 Aggarwal Cyber Plaza
 *						  Netaji Subhash Place, Delhi - 110034
 *						  www.gigapromoters.com
 * 
 *
 * @version 			$Rev: 63 $
 * @lastModifiedBy		$LastChangedBy: shrey $
 * @lastChanged			$Date: 2014-11-10 10:45:30 +0530 (Mon, 10 Nov 2014) $
 * @copyright 			Giga Promoters (www.gigapromoters.com)
 * 
 */

/**
 * Taggable behavior. Attach it to any model and it'll take care of saving process for tags.
 * When attached to a model it does two things:
 * 1. Saves all specified tags into tags table.
 * 2. Saves type & item_id into tagged items table with tag_id.
 * 
 * This function require some refactoring and verification of unit tests.
 *
 */
class TaggableBehavior extends ModelBehavior {
	
	var $model;
	var $savedTags;
	var $deleteExisting = true;//deletes all tags related to item before insertion of new tag i.e on edit
	
	function setup(AppModel $model,$config) {
		if(isset($config['deleteExisting']))
		{
			$this->deleteExisting = $config['deleteExisting'];
		}
		$this->model = $model;
		$model->additionalFields[] = 'tags';
		$model->cacheFields['tags'] = 'onUpdate';
		
	}
	/**
	 * To insert tags in 'tags' table
	 *
	 * @param unknown_type $model
	 * @return unknown
	 */
	function beforeSave(&$model)
	{
		// to fix problem at server
		$this->model = $model;
		// to avoid un-necessary triggering of these functions
		if(!isset($this->model->data['Tag']['tag']))
		{
			return true;
		}
		if(is_array($this->model->data['Tag']['tag']))
		{
			$this->savedTags = $this->model->data['Tag']['tag'];
			return true;
		}
		App::import('Model', 'Tags.Tag');
		$tagModel = &new Tag();
		$this->savedTags = array();
		$tags = explode(',',$this->model->data['Tag']['tag']);
		$this->model->data['Tag']['tag'] = array();
		foreach($tags as $tag)
		{
			$newTag = array();
			$newTag['Tag']['tag'] = trim($tag);
			
			if($newTag['Tag']['tag']=='')
				continue;
			
			if(!$tagRec = $tagModel->findBytag($newTag['Tag']['tag']))
			{
				$tagModel->save($newTag);
				$this->savedTags[] = $tagModel->id;
				$tagModel->id = '';
			}
			else
			{
				$this->savedTags[] = $tagRec['Tag']['id'];
			}
		}


	}

	/**
	 * To store tags and relations after saving main item
	 *
	 * @param unknown_type $model
	 * @return unknown
	 */
	function afterSave(&$model,$created)
	{
		// to fix problem at server
		$this->model = $model;

		// to avoid un-necessary triggering of these functions
		
		if(!isset($this->savedTags) && !isset($this->model->data['Tag']['tag']))
		{
			return true;
		}

		$item_id = $this->model->id;

		App::import('Model', 'Tags.TaggedItem');
		$taggedItemModel = &new TaggedItem();
		if($created != true &&  $this->deleteExisting==true && (!isset($this->model->data['Tag']['deleteExisting']) || $this->model->data['Tag']['deleteExisting'] !=1))
		{
			$taggedItemModel->deleteAll(array('item_id'=>$item_id,'type'=>$this->model->name));
		}
		if(isset($this->savedTags))
		{
			foreach($this->savedTags as $tagId)
			{
				$taggedItem = array();
				$taggedItem['TaggedItem']['tag_id'] = $tagId;
				$taggedItem['TaggedItem']['item_id'] = $item_id;
				$taggedItem['TaggedItem']['type'] = $this->model->name;

				$taggedItemModel->save($taggedItem);

				$taggedItemModel->id = null;
			}
		}

	}
	function afterDelete(&$model)
	{
		$item_id = $model->id;
		$type = $model->name;
		ClassRegistry::init('Tags.TaggedItem')->deleteAll(array('item_id'=>$item_id,'type'=>$type));
		return true;
	}
	
	function tags($model,$record)
	{
		$tags = array();
		if(isset($record[$model->alias]['id']))
		{
			$taggedItems = ClassRegistry::init('Tags.TaggedItem')->find('list',array('conditions'=>array('item_id'=>$record[$model->alias]['id'],'type'=>$model->name),'fields'=>array('tag_id')));
			$tags = ClassRegistry::init('Tags.Tag')->find('all',array('conditions'=>array('id'=>$taggedItems),'recursive'=>-1));
		}
		$tags = Set::combine($tags,'{n}.Tag.id','{n}.Tag');
		return $tags;
	}
	
	

}
?>